#include <public/version.h>
#include <public/memory.h>
-int hvm_enabled;
+int hvm_enabled __read_mostly;
-unsigned int opt_hvm_debug_level;
+unsigned int opt_hvm_debug_level __read_mostly;
integer_param("hvm_debug", opt_hvm_debug_level);
-struct hvm_function_table hvm_funcs;
+struct hvm_function_table hvm_funcs __read_mostly;
/* I/O permission bitmap is globally shared by all HVM guests. */
char __attribute__ ((__section__ (".bss.page_aligned")))
hvm_io_bitmap[3*PAGE_SIZE];
-void hvm_enable(void)
+void hvm_enable(struct hvm_function_table *fns)
{
if ( hvm_enabled )
return;
memset(hvm_io_bitmap, ~0, sizeof(hvm_io_bitmap));
clear_bit(0x80, hvm_io_bitmap);
+ hvm_funcs = *fns;
hvm_enabled = 1;
}
return vmcb->exitintinfo.fields.v;
}
+static struct hvm_function_table svm_function_table = {
+ .disable = stop_svm,
+ .vcpu_initialise = svm_vcpu_initialise,
+ .vcpu_destroy = svm_vcpu_destroy,
+ .store_cpu_guest_regs = svm_store_cpu_guest_regs,
+ .load_cpu_guest_regs = svm_load_cpu_guest_regs,
+ .save_cpu_ctxt = svm_save_vmcb_ctxt,
+ .load_cpu_ctxt = svm_load_vmcb_ctxt,
+ .paging_enabled = svm_paging_enabled,
+ .long_mode_enabled = svm_long_mode_enabled,
+ .pae_enabled = svm_pae_enabled,
+ .guest_x86_mode = svm_guest_x86_mode,
+ .get_guest_ctrl_reg = svm_get_ctrl_reg,
+ .get_segment_base = svm_get_segment_base,
+ .get_segment_register = svm_get_segment_register,
+ .update_host_cr3 = svm_update_host_cr3,
+ .update_guest_cr3 = svm_update_guest_cr3,
+ .update_vtpr = svm_update_vtpr,
+ .stts = svm_stts,
+ .set_tsc_offset = svm_set_tsc_offset,
+ .inject_exception = svm_hvm_inject_exception,
+ .init_ap_context = svm_init_ap_context,
+ .init_hypercall_page = svm_init_hypercall_page,
+ .event_injection_faulted = svm_event_injection_faulted
+};
+
int start_svm(void)
{
u32 eax, ecx, edx;
if (cpu == 0)
setup_vmcb_dump();
- /* Setup HVM interfaces */
- hvm_funcs.disable = stop_svm;
-
- hvm_funcs.vcpu_initialise = svm_vcpu_initialise;
- hvm_funcs.vcpu_destroy = svm_vcpu_destroy;
-
- hvm_funcs.store_cpu_guest_regs = svm_store_cpu_guest_regs;
- hvm_funcs.load_cpu_guest_regs = svm_load_cpu_guest_regs;
-
- hvm_funcs.save_cpu_ctxt = svm_save_vmcb_ctxt;
- hvm_funcs.load_cpu_ctxt = svm_load_vmcb_ctxt;
-
- hvm_funcs.paging_enabled = svm_paging_enabled;
- hvm_funcs.long_mode_enabled = svm_long_mode_enabled;
- hvm_funcs.pae_enabled = svm_pae_enabled;
- hvm_funcs.guest_x86_mode = svm_guest_x86_mode;
- hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg;
- hvm_funcs.get_segment_base = svm_get_segment_base;
- hvm_funcs.get_segment_register = svm_get_segment_register;
-
- hvm_funcs.update_host_cr3 = svm_update_host_cr3;
- hvm_funcs.update_guest_cr3 = svm_update_guest_cr3;
-
- hvm_funcs.update_vtpr = svm_update_vtpr;
-
- hvm_funcs.stts = svm_stts;
- hvm_funcs.set_tsc_offset = svm_set_tsc_offset;
-
- hvm_funcs.inject_exception = svm_hvm_inject_exception;
-
- hvm_funcs.init_ap_context = svm_init_ap_context;
- hvm_funcs.init_hypercall_page = svm_init_hypercall_page;
-
- hvm_funcs.event_injection_faulted = svm_event_injection_faulted;
-
- hvm_enable();
+ hvm_enable(&svm_function_table);
return 1;
}
return (idtv_info_field & INTR_INFO_VALID_MASK);
}
-/* Setup HVM interfaces */
-static void vmx_setup_hvm_funcs(void)
-{
- hvm_funcs.disable = stop_vmx;
-
- hvm_funcs.vcpu_initialise = vmx_vcpu_initialise;
- hvm_funcs.vcpu_destroy = vmx_vcpu_destroy;
-
- hvm_funcs.store_cpu_guest_regs = vmx_store_cpu_guest_regs;
- hvm_funcs.load_cpu_guest_regs = vmx_load_cpu_guest_regs;
-
- hvm_funcs.save_cpu_ctxt = vmx_save_vmcs_ctxt;
- hvm_funcs.load_cpu_ctxt = vmx_load_vmcs_ctxt;
-
- hvm_funcs.paging_enabled = vmx_paging_enabled;
- hvm_funcs.long_mode_enabled = vmx_long_mode_enabled;
- hvm_funcs.pae_enabled = vmx_pae_enabled;
- hvm_funcs.guest_x86_mode = vmx_guest_x86_mode;
- hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg;
- hvm_funcs.get_segment_base = vmx_get_segment_base;
- hvm_funcs.get_segment_register = vmx_get_segment_register;
-
- hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
- hvm_funcs.update_guest_cr3 = vmx_update_guest_cr3;
-
- hvm_funcs.update_vtpr = vmx_update_vtpr;
-
- hvm_funcs.stts = vmx_stts;
- hvm_funcs.set_tsc_offset = vmx_set_tsc_offset;
-
- hvm_funcs.inject_exception = vmx_inject_exception;
-
- hvm_funcs.init_ap_context = vmx_init_ap_context;
-
- hvm_funcs.init_hypercall_page = vmx_init_hypercall_page;
-
- hvm_funcs.event_injection_faulted = vmx_event_injection_faulted;
-}
+static struct hvm_function_table vmx_function_table = {
+ .disable = stop_vmx,
+ .vcpu_initialise = vmx_vcpu_initialise,
+ .vcpu_destroy = vmx_vcpu_destroy,
+ .store_cpu_guest_regs = vmx_store_cpu_guest_regs,
+ .load_cpu_guest_regs = vmx_load_cpu_guest_regs,
+ .save_cpu_ctxt = vmx_save_vmcs_ctxt,
+ .load_cpu_ctxt = vmx_load_vmcs_ctxt,
+ .paging_enabled = vmx_paging_enabled,
+ .long_mode_enabled = vmx_long_mode_enabled,
+ .pae_enabled = vmx_pae_enabled,
+ .guest_x86_mode = vmx_guest_x86_mode,
+ .get_guest_ctrl_reg = vmx_get_ctrl_reg,
+ .get_segment_base = vmx_get_segment_base,
+ .get_segment_register = vmx_get_segment_register,
+ .update_host_cr3 = vmx_update_host_cr3,
+ .update_guest_cr3 = vmx_update_guest_cr3,
+ .update_vtpr = vmx_update_vtpr,
+ .stts = vmx_stts,
+ .set_tsc_offset = vmx_set_tsc_offset,
+ .inject_exception = vmx_inject_exception,
+ .init_ap_context = vmx_init_ap_context,
+ .init_hypercall_page = vmx_init_hypercall_page,
+ .event_injection_faulted = vmx_event_injection_faulted
+};
int start_vmx(void)
{
vmx_save_host_msrs();
- vmx_setup_hvm_funcs();
-
- hvm_enable();
+ hvm_enable(&vmx_function_table);
return 1;
}
static inline void
hvm_disable(void)
{
- if ( hvm_funcs.disable )
- hvm_funcs.disable();
+ hvm_funcs.disable();
}
int hvm_domain_initialise(struct domain *d);
static inline unsigned long
hvm_get_guest_ctrl_reg(struct vcpu *v, unsigned int num)
{
- if ( hvm_funcs.get_guest_ctrl_reg )
- return hvm_funcs.get_guest_ctrl_reg(v, num);
- return 0; /* force to fail */
+ return hvm_funcs.get_guest_ctrl_reg(v, num);
}
static inline unsigned long
extern char hvm_io_bitmap[];
extern int hvm_enabled;
-void hvm_enable(void);
+void hvm_enable(struct hvm_function_table *);
int hvm_copy_to_guest_phys(paddr_t paddr, void *buf, int size);
int hvm_copy_from_guest_phys(void *buf, paddr_t paddr, int size);